package timer;

import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public abstract class MyTimer extends TimerTask
{
	private static int						poolSize	= 30;
	private static ScheduledExecutorService	pool		= null;
	private Long							_delay		= null;
	private Long							_period		= null;
	private Long							_count		= null;
	{
		if (pool == null)
		{
			pool = Executors.newScheduledThreadPool(poolSize);
		}
	}

	public void scheduleOnce(long delay)
	{
		_delay = delay;
		schedule();
	}

	public void scheduleLoop(long delay, long period)
	{
		_delay = delay;
		_period = period;
		schedule();
	}

	public void scheduleNum(long delay, long period, long count)
	{
		_delay = delay;
		_period = period;
		_count = count;
		schedule();
	}

	private void schedule()
	{
		onStart();
		if (_delay == null)
		{
			System.err.println("err, not set delay");
			return;
		}
		else if (_period == null)
		{
			pool.schedule(this, _delay, TimeUnit.MILLISECONDS);
		}
		else if (_count == null)
		{
			pool.scheduleAtFixedRate(this, _delay, _period, TimeUnit.MILLISECONDS);
		}
		else
		{
			ScheduledFuture<?> future = pool.scheduleAtFixedRate(this, _delay, _period, TimeUnit.MILLISECONDS);
			long cancelTime = _delay + _period * (_count - 1) + 1;
			CancelTask cancel = new CancelTask(future);
			pool.schedule(cancel, cancelTime, TimeUnit.MILLISECONDS);
		}
	}

	public void run()
	{
		onTimer();
	}

	public abstract void onStart();

	public abstract void onTimer();

	static class CancelTask implements Runnable
	{
		private ScheduledFuture<?>	_future;

		public CancelTask(ScheduledFuture<?> future)
		{
			_future = future;
		}

		@Override
		public void run()
		{
			_future.cancel(false);
		}
	}
}
